package top.honlnk.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.honlnk.common.config.ConstantConfig;
import top.honlnk.common.constant.AdminConstant;
import top.honlnk.mapper.AdminMapper;
import top.honlnk.mapper.PublicMapper;
import top.honlnk.common.network.TableToRotaNetwork;
import top.honlnk.pojo.dto.AdminGetKeyDTO;
import top.honlnk.pojo.dto.AdminUpdateRotaDTO;
import top.honlnk.pojo.dto.TableToRotaDTO;
import top.honlnk.pojo.entity.RotaSecretKey;
import top.honlnk.pojo.entity.SchoolTimetable;
import top.honlnk.pojo.vo.AdminGetRotaListVO;
import top.honlnk.pojo.vo.AdminGetUserTableVO;
import top.honlnk.service.impl.processor.AnalysisAdminKeyProcessor;
import top.honlnk.service.impl.processor.GenerateAdminKeyProcessor;
import top.honlnk.common.utils.StringToArrayUtil;
import top.honlnk.service.AdminService;

import java.time.LocalDate;
import java.util.*;


@Slf4j
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private PublicMapper publicMapper;

    @Autowired
    private ConstantConfig constantConfig;

    @Override
    public String produceKey(AdminGetKeyDTO adminGetKeyDTO) {
        GenerateAdminKeyProcessor generateAdminKeyProcessor = new GenerateAdminKeyProcessor();
        String AdminKey = generateAdminKeyProcessor.getKey(adminGetKeyDTO);
        RotaSecretKey rotaSecretKey = RotaSecretKey.builder()
                .adminKey(AdminKey)
                .time(LocalDate.now())
                .build();

        // 使用模糊查询，将生成的密钥前11位拿去数据库中查询，如果能查得到，说明有重复（当然可能性不大）
        RotaSecretKey rotaSecretKeyLike = publicMapper.getRotaSecretKeyLike(AdminKey.substring(0, 11));
        if (rotaSecretKeyLike != null) {
            throw new RuntimeException(AdminConstant.THE_CHOSEN_ONE);
        }
        adminMapper.insert(rotaSecretKey);
        return AdminKey;
    }

    @Override
    public void updateRota(@NotNull AdminUpdateRotaDTO adminUpdateRotaDTO, String key) {
        String rota = Arrays.deepToString(adminUpdateRotaDTO.getRota());
        adminMapper.updateRota(rota, key);
    }


    @Override
    public AdminGetRotaListVO produceRota(String key) {
        int keyId = adminMapper.getRotaSecretKey(key).getId();
        // 获取密钥对应的所有的课程表以及名字
        List<SchoolTimetable>  rotaMapList = adminMapper.getSchoolTimetableList(keyId);
        // 将获取的数据转换为需要的标准的json格式
        Map<String, String[][]> desiredFormat = convertToDesiredFormat(rotaMapList);

        // 提取key的最后两个字符并分别赋值给classes和num
        char[] lastTwoCharsArray = key.substring(0, 13).toCharArray();
        String classesString = String.valueOf(lastTwoCharsArray[11]);
        String numString = String.valueOf(lastTwoCharsArray[12]);

        AnalysisAdminKeyProcessor analysisAdminKeyProcessor = new AnalysisAdminKeyProcessor();
        Integer classes = analysisAdminKeyProcessor.getNumber(classesString);
        Integer num = analysisAdminKeyProcessor.getNumber(numString);

        TableToRotaDTO tableToRotaDTO = TableToRotaDTO.builder()
                .classes(classes)
                .num(num)
                .data(desiredFormat)
                .build();
        TableToRotaNetwork tableToRotaNetwork = new TableToRotaNetwork();
        List<List<List<String>>> rota = tableToRotaNetwork.tableToRota(tableToRotaDTO, constantConfig.getUrl());
        log.info("rota: {}", rota.toString());
        AdminGetRotaListVO adminGetRotaListVO = AdminGetRotaListVO.builder()
                .rota(rota)
                .build();
        adminMapper.updateRota(Arrays.deepToString(rota.toArray()), key);
        return adminGetRotaListVO;
    }

    @Override
    public List<AdminGetUserTableVO> getUserTable(String key) {
        List<SchoolTimetable> schoolTimetableList = adminMapper.getUserTable(key);
        List<AdminGetUserTableVO> resultList = new ArrayList<>();
        for (SchoolTimetable schoolTimetable : schoolTimetableList) {
            String tableString =  schoolTimetable.getTable();
            StringToArrayUtil stringToArrayUtil = new StringToArrayUtil();
            String[][] tableArray = stringToArrayUtil.stringTo2DArray(tableString);

            resultList.add(AdminGetUserTableVO.builder()
                    .name(schoolTimetable.getName())
                    .submitId(schoolTimetable.getSubmitId())
                    .table(tableArray)
                    .build());
        }
        return resultList;
    }

    @Override
    public void deleteUserTable(String submitId) {
        adminMapper.deleteSchoolTimetable(submitId);
    }

    private static @NotNull Map<String, String[][]> convertToDesiredFormat(@NotNull List<SchoolTimetable> originalData) {
        Map<String, String[][]> desiredFormat = new HashMap<>();

        for (SchoolTimetable record : originalData) {
            String name = record.getName();
            String table = record.getTable();
            StringToArrayUtil stringToArrayUtil = new StringToArrayUtil();
            String[][] tableArray = stringToArrayUtil.stringTo2DArray(table);

            desiredFormat.put(name, tableArray);
        }

        return desiredFormat;
    }
}
